![ARを使ったアプリでよく見るARCoachingOverlayViewを使ってみる](https://devio2023-media.developers.io/wp-content/uploads/2022/05/ar-coaching-overlay-view-eyecatch.png)
ARを使ったアプリでよく見るARCoachingOverlayViewを使ってみる
ARを使ったアプリでよく見かける起動した後に表示されるオンボーディングを使いたかったので調べることにしました。
環境
- Xcode 13.3
- iPhone 12mini
はじめに
先日、紹介した垂直方向の平面にアート作品を置くアプリにARCoachingOverlayView
を導入して使ってみたいと思います。
ARCoachingOverlayViewとは
特定のゴールに向けてユーザーに標準化された作業指示を表示するView
です。特定のゴールとは、今回のような垂直面を検出する必要があるアプリだと、垂直面を検出する為にユーザーに指示を出します。
ARCoachingOverlayView
が表示されると下記のようなView
が表示されます。
ARKit
がトラッキングを確立するには、ユーザーはデバイスを実際に動かして、ARKit
が遠近感を得ることができるようにする必要があります。
アプリを起動すると、Coaching Overlayは、ARKitがトラッキングを確立するのを手助けする為にユーザーにデバイスを移動するように求めます。特定の目標を設定した場合、Coaching Overlayはそれに応じて画面に表示する指示を調整します。Coaching Overlayが目標が達成されたと判断し、それ以上のコーチングが不要になると、ユーザーのViewから非表示になります。
ARCoachingOverlayViewを実装する
こちらで作成したアプリのARViewContainer
にARCoachingOverlayView
を実装していきます。
import RealityKit import ARKit import SwiftUI struct ARViewContainer: UIViewRepresentable { func makeUIView(context: Context) -> ARView { print("makeUI") let arView = ARView(frame: .zero, cameraMode: .ar, automaticallyConfigureSession: true) arView.addTapGesture() // CoachingOverlayViewをインスタンス化 let coachingOverlayView = ARCoachingOverlayView() // ARViewのセッションに対応 coachingOverlayView.session = arView.session // Delegateを設定 coachingOverlayView.delegate = context.coordinator // アプリの追跡要件を指示する為のゴール coachingOverlayView.goal = .verticalPlane // セッション状態によって自動でアクティベートするか coachingOverlayView.activatesAutomatically = true // サイズの調整 coachingOverlayView.autoresizingMask = [.flexibleWidth, .flexibleHeight] // ARViewにARCoachingOverlayViewを追加 arView.addSubview(coachingOverlayView) return arView } func updateUIView(_ uiView: ARView, context: Context) {} func makeCoordinator() -> Coordinator { Coordinator(self) } class Coordinator: NSObject, ARCoachingOverlayViewDelegate { let parent: ARViewContainer init(_ parent: ARViewContainer) { self.parent = parent } func coachingOverlayViewWillActivate(_ coachingOverlayView: ARCoachingOverlayView) { // CoachingOverlayViewがアクティブになるタイミングで呼ばれる処理 } func coachingOverlayViewDidDeactivate(_ coachingOverlayView: ARCoachingOverlayView) { // Coaching Overlayが完全に非アクティブ化されたときに呼ばれる処理 } func coachingOverlayViewDidRequestSessionReset(_ coachingOverlayView: ARCoachingOverlayView) { // セッションの再ローカライズ中に、ユーザーがCoachingOverlayViewの[最初からやり直す]ボタンをタップしたときに呼ばれる処理 } } }
CoachingOverlayViewを追加する
今回の例ではmakeUIView
内でARCoachingOverlayView
を追加しています。
// CoachingOverlayViewをインスタンス化 let coachingOverlayView = ARCoachingOverlayView() // ARViewのセッションに対応 coachingOverlayView.session = arView.session // Delegateを設定 coachingOverlayView.delegate = context.coordinator // アプリの追跡要件を指示する為のゴール coachingOverlayView.goal = .verticalPlane // セッション状態によって自動でアクティベートするか coachingOverlayView.activatesAutomatically = true // サイズの調整 coachingOverlayView.autoresizingMask = [.flexibleWidth, .flexibleHeight] // ARViewにARCoachingOverlayViewを追加 arView.addSubview(coachingOverlayView)
まずは、ARCoachingOverlayView
のインスタンスを生成し、ARView
のセッションに対応する為にARView
のセッションをcoachingOverlayView.session
に代入しています。ARCoachingOverlayView
にはDelegateメソッドがある為、後述するCoordinator
をcoachingOverlayView.delegate
代入しておきます。
アプリの追跡要件を指示する為のゴール
今回は垂直方向の平面.verticalPlane
をゴールとして設定しました。
coachingOverlayView.goal = .verticalPlane
こちらの設定した値によって、ARCoachingOverlayView
が画面に表示するオンボーディング内容が変わってきます。
ARCoachingOverlayView.Goal
は列挙型で指定できるオプションは他にもあります。
case anyPlane
- ゴールとして、任意のタイプの平面を要求します。
case horizontalPlane
- ゴールとして、水平面を要求します。
case tracking
- ゴールとして、基本的なワールドトラッキングを要求します。
case verticalPlane
- ゴールとして、垂直面を要求します。
case geoTracking
- ゴールとして、正確な地理的位置を要求します。
実際のARアプリの内容に合うゴールを設定しましょう。
セッション状態によって自動でアクティベートする
Coaching Overlayを自動的にセットするようにcoachingOverlayView.activatesAutomatically
にtrue
を設定しています。
coachingOverlayView.activatesAutomatically = true
今回は明示的にtrue
を設定していますが、デフォルト値はtrue
なので、この記述は書かなくても問題ありません。
activatesAutomatically
にtrue
をセットすることでセッションが初期化された時、またはトラッキング状態が特定のしきい値を超えて低下した際に自動的にARCoachingOverlayView
がアクティブになり表示されます。
ARViewにARCoachingOverlayViewを追加
// サイズの調整 coachingOverlayView.autoresizingMask = [.flexibleWidth, .flexibleHeight] // ARViewにARCoachingOverlayViewを追加 arView.addSubview(coachingOverlayView)
autoresizingMask
に.flexibleWidth
と.flexibleHeight
を設定して、ARView
のbounds
に応じて幅、高さともに柔軟にリサイズされるようにしておきます。
最後にARView
にaddSubview(coachingOverlayView)
して完成です。
ARCoachingOverlayViewDelegate
Coordinator
内で記述しているDelegateについての説明です。
class Coordinator: NSObject, ARCoachingOverlayViewDelegate { let parent: ARViewContainer init(_ parent: ARViewContainer) { self.parent = parent } func coachingOverlayViewWillActivate(_ coachingOverlayView: ARCoachingOverlayView) { // CoachingOverlayViewがアクティブになるタイミングで呼ばれる処理 } func coachingOverlayViewDidDeactivate(_ coachingOverlayView: ARCoachingOverlayView) { // Coaching Overlayが完全に非アクティブ化されたときに呼ばれる処理 } func coachingOverlayViewDidRequestSessionReset(_ coachingOverlayView: ARCoachingOverlayView) { // セッションの再ローカライズ中に、ユーザーがCoachingOverlayViewの[最初からやり直す]ボタンをタップしたときに呼ばれる処理 } }
coachingOverlayViewWillActivate
文字通り、ARCoachingOverlayView
がアクティブになるタイミングで呼ばれるメソッドです。
AppleのサンプルアプリではARアプリの状態を表示したり、コントロールする為のViewを非表示にする処理を行なっておりました。
例
func coachingOverlayViewWillActivate(_ coachingOverlayView: ARCoachingOverlayView) { upperControlsView.isHidden = true }
coachingOverlayViewDidDeactivate
Coaching Overlayが目標が達成されたと判断するとユーザーのViewから消え、コーチングプロセスが終了するタイミングで呼ばれるメソッドです。
AppleのサンプルアプリではARアプリの状態を表示したり、コントロールする為のViewを表示させて、アプリが操作できることを視覚的に表現しておりました。
例
func coachingOverlayViewDidDeactivate(_ coachingOverlayView: ARCoachingOverlayView) { upperControlsView.isHidden = false }
coachingOverlayViewDidRequestSessionReset
セッションの再ローカライズ中に、ARCoachingOverlayView
上にStart Overボタンが出てきます。そのボタンを押した時に呼ばれるメソッドです。
Start Overは、最初からやり直すの意味で、AppleのサンプルアプリではAR空間上の状態をリセットする処理を行なっておりました。
例
func coachingOverlayViewDidRequestSessionReset(_ coachingOverlayView: ARCoachingOverlayView) { restartExperience() }
おわりに
ARアプリを作成する際は、トラッキングを促進させる為にもARCoachingOverlayView
を使用した方がよさそうですね。
今回、ARCoachingOverlayView
の動きを確認する為にAppleがサンプルコードで提供しているサンプルプロジェクトを実機に入れて使ってみたのですが、シンプルながら内容も充実しておりとても良かったです。
同じような物を作る時はとても参考になりそうだと感じました。
Appleサンプルアプリのデモ
モバイルアプリ開発のチームメンバー絶賛募集中!
モバイル事業部では事業会社様と一緒に、数年間にわたり長期でモバイルアプリをグロースさせています。
そんなモバイルアプリ開発のチームメンバーを絶賛募集中です!
もちろんモバイルアプリ開発以外のエンジニアも募集中です!